package demo.android.myapplication.demos.touch

import android.content.Context
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.VelocityTracker
import android.view.ViewConfiguration
import android.view.ViewGroup
import android.widget.OverScroller
import androidx.core.view.forEach
import cn.android.basic.float
import cn.android.basic.int
import kotlin.math.abs

/**
 * Created by guoshiwen on 2021/7/29.
 */
class TwoPageView @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : ViewGroup(context, attrs, defStyleAttr) {
    val vc = ViewConfiguration.get(context)
    val velocityTracker = VelocityTracker.obtain()
    val scroller = OverScroller(context)

    val pageSlop = vc.scaledPagingTouchSlop

    var downX = 0f
    var downY = 0f
    var scrolledX = 0

    var scrolling = false

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        measureChildren(widthMeasureSpec, heightMeasureSpec)
    }

    override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
        var offsetX = 0
        forEach {child->
            child.layout(offsetX, 0, offsetX+child.measuredWidth, child.measuredHeight)
            offsetX+=child.measuredWidth
        }
    }

    override fun onInterceptTouchEvent(ev: MotionEvent): Boolean {
        if(ev.actionMasked == MotionEvent.ACTION_DOWN){
            velocityTracker.clear()
            downX = ev.x
            downY = ev.y
            scrolling = false
            scrolledX = scrollX
        }

        velocityTracker.addMovement(ev)

        var result = super.onInterceptTouchEvent(ev)
        when(ev.actionMasked) {
            MotionEvent.ACTION_MOVE -> {
                val dx = ev.x - downX
                if(!scrolling && abs(dx) >= pageSlop){
                    parent.requestDisallowInterceptTouchEvent(true)
                    scrolling = true
                    result = true
                }

            }
        }
        return result
    }

    override fun onTouchEvent(ev: MotionEvent): Boolean {
        if(ev.actionMasked == MotionEvent.ACTION_DOWN){
            velocityTracker.clear()
            downX = ev.x
            downY = ev.y
            scrolledX = scrollX
        }

        velocityTracker.addMovement(ev)

        when(ev.actionMasked) {
            MotionEvent.ACTION_MOVE -> {
                val dx = (ev.x - downX - scrolledX).int.coerceAtLeast(-width).coerceAtMost(0)
                scrollTo(-dx, 0)
            }
            MotionEvent.ACTION_UP -> {
                scrolledX = scrollX
                velocityTracker.computeCurrentVelocity(1000, vc.scaledMaximumFlingVelocity.float)
                val vx = velocityTracker.xVelocity
                val targetPage = if(abs(vx) < vc.scaledMinimumFlingVelocity){
                    if(scrolledX > width / 2) 1 else 0
                }else {
                    if(vx < 0) 1 else 0
                }
                val scrollDistance = if (targetPage == 1) width - scrolledX else -scrolledX
                scroller.startScroll(scrolledX, 0, scrollDistance, 0)
                postInvalidateOnAnimation()
            }
        }
        return true
    }

    override fun computeScroll() {
        if (scroller.computeScrollOffset()) {
            scrollTo(scroller.currX, scroller.currY)
            postInvalidateOnAnimation()
        }
    }
}